package com.xuetang9.fujian.view;

import com.xuetang9.fujian.mychat.entity.BizType;
import com.xuetang9.fujian.mychat.entity.Message;
import com.xuetang9.fujian.mychat.entity.User;
import com.xuetang9.fujian.mychat.util.SysDTO;
import com.xuetang9.fujian.net.ClientV1;

import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author: fujian
 * @description:
 * @date: 2021/5/11 9:20
 * @version: V1.0
 * @package: com.xuetang9.fujian.view
 **/
public class ChatFrame extends JFrame {
    private boolean isRunning;
    private ClientV1 client;
    private User loginUser;
    private JList<String> listFriends = new JList<>();          // 用来显示当前在线所有的用户名称
    private JTextPane txtChatRecord = new JTextPane();          // 副文本框，可以更改文字的样式
    private JTextArea txtSendMessage = new JTextArea();       //发送消息文本框
    private JPanel contentPane = (JPanel) getContentPane();
    private JButton btnSendMessage = new JButton("发送");
    private StyledDocument styledDocument = null;           //是JTextPanel的配套样式文档
    private SimpleAttributeSet attributeSet1 = new SimpleAttributeSet();
    private SimpleAttributeSet attributeSet2 = new SimpleAttributeSet();

    public ChatFrame(User loginUser, ClientV1 client){
        this.client = client;
        this.loginUser = loginUser;
        this.isRunning = true;
        this.styledDocument = txtChatRecord.getStyledDocument();
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(800,600);
        initComponents();
        setLocationRelativeTo(null);
        setTitle("当前登录用户:" + loginUser.getNickName());
        setVisible(true);
        new Thread(new SendRequestTask()).start();
        new Thread(new UpdateTask()).start();

    }

    private void initComponents() {
        DefaultListModel<String> listModel = new DefaultListModel<>();
        listModel.addElement("测试用户1");
        listModel.addElement("测试用户2");
        listFriends.setModel(listModel);
        // 水平分割面板
        JSplitPane splitPane_h = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPane_h.setDividerLocation(150); // 设置水平分割面板的左侧位置
        splitPane_h.setDividerSize(10);      // 设置分割线的宽度
        //垂直分割面板
        JSplitPane splitPane_v = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        splitPane_v.setDividerLocation(400);
        splitPane_v.setDividerSize(10);
        txtChatRecord.setEditable(false);
        splitPane_v.add(new JScrollPane(txtChatRecord));
        splitPane_v.add(creatSendMessagePane());
        // 添加左侧好友列表控件
        splitPane_h.add(new JScrollPane(listFriends));
        // 垂直面板在水平面板之中
        splitPane_h.add(splitPane_v);
        contentPane.add(splitPane_h,BorderLayout.CENTER);
        
        setSimpleAttributeSet();
        
        btnSendMessage.addActionListener(e->{
            btnSendMessageActionPerformed(e);
        });

        // 监测窗体的关闭事件
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                // 首先将本窗体隐藏，
                ChatFrame.this.setVisible(false);
                // 发送退出消息给服务器
                client.close(loginUser.getNickName());
                try {
                    TimeUnit.MILLISECONDS.sleep(2000);
                } catch (InterruptedException interruptedException) {
                    interruptedException.printStackTrace();
                }
                // 等待几秒钟，客户端断开连接
                System.exit(0);
            }
        });
    }

    private void setSimpleAttributeSet() {
        StyleConstants.setForeground(attributeSet1,Color.RED);
        StyleConstants.setFontSize(attributeSet1,24);
        StyleConstants.setUnderline(attributeSet1,true);
        StyleConstants.setForeground(attributeSet2,Color.BLUE.darker());
        StyleConstants.setFontSize(attributeSet2,18);
    }

    private void btnSendMessageActionPerformed(ActionEvent e) {
        String toUserName = listFriends.getSelectedValue();
        if (null == toUserName)return;
        SysDTO dto = new SysDTO(BizType.发送消息);
        Message message = new Message();
        message.setFromUserName(loginUser.getNickName());
        message.setToUserNickName(toUserName);
        message.setSendTime(LocalDateTime.now());
        message.setContent(txtSendMessage.getText());
        dto.setMessage(message);
        try {
            client.sendDTO(dto);
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
        txtSendMessage.setText("");
    }

    private JPanel creatSendMessagePane(){
        JPanel panel = new JPanel(new BorderLayout());
        JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        buttonPane.add(btnSendMessage);
        panel.add(new JScrollPane(txtSendMessage),BorderLayout.CENTER);
        panel.add(buttonPane,BorderLayout.SOUTH);
        return panel;
    }
    /**
     * @author fujian
     * @ClassName: ChatFrame
     * @desctiption 定时向服务端发送业务请求，获得当前在线的所有用户名
     * @date 2021/5/11 10:08
     * @version V1.0
    **/
    class SendRequestTask implements Runnable{

        @Override
        public void run() {
            while (isRunning){
                SysDTO dto = new SysDTO(BizType.获得好友);
                dto.setNickName(loginUser.getNickName());
                try {
                    client.sendDTO(dto); // 请求任务中，只负责向服务端请求，不负责接收
                    TimeUnit.MILLISECONDS.sleep(3000);
                } catch (IOException | InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * @author fujian
     * @ClassName: ChatFrame
     * @desctiption 更新线程，等待服务端返回的dto对象，如果没有返回，就阻塞
     * 一旦获得服务端的dto对象，就根据dto对象的结果更新当前界面数据
     * @date 2021/5/11 10:13
     * @version V1.0
    **/
    class UpdateTask implements Runnable{

        @Override
        public void run() {
            while (isRunning){
                SysDTO dto = null;
                try {
                    dto = client.readDto();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                if (dto.getBizType() == BizType.获得好友成功){
                    // dto中要添加好友列表
                    List<User> userList = dto.getUserList();
                    if (null == userList || userList.isEmpty()){
                        continue;
                    }
                    int selectIndex = listFriends.getSelectedIndex();
                    // 如果有新用户，就更新界面
                    DefaultListModel<String> listModel = new DefaultListModel<>();
                    for (User user : userList) {
                        listModel.addElement(user.getNickName());
                    }
                    listFriends.setModel(listModel);
                    if (selectIndex != -1){
                        listFriends.setSelectedIndex(selectIndex);
                    }
                }
                else if (dto.getBizType() == BizType.您有新消息了){
                    Message message = dto.getMessage();
                    String recordInfo = String.format("%s(%s)\r\n",message.getFromUserName(),message.getStrSendTime());
                    String record = "  " + message.getContent() + "\r\n";
                    // 将两行数据显示在文字面板上
                    try {
                        styledDocument.insertString(styledDocument.getLength(),recordInfo,attributeSet1);
                        styledDocument.insertString(styledDocument.getLength(),record,attributeSet2);
                    } catch (BadLocationException e) {
                        e.printStackTrace();
                    }
                }
                else if (dto.getBizType() == BizType.退出成功){
                    isRunning = false;
                    break;
                }
            }
            System.out.println("更新线程已结束");
        }
    }

    public static void main(String[] args) {
        new ChatFrame(null,null);
    }

}
